/*
 * SHOPTNT 版权所有。
 * 未经许可，您不得使用此文件。
 * 官方地址：www.shoptnt.cn
 */
package cn.shoptnt.service.trade.order.impl;

import cn.shoptnt.model.promotion.coupon.enums.CouponUseScope;
import cn.shoptnt.model.promotion.coupon.vo.GoodsCouponPrice;
import cn.shoptnt.model.trade.cart.vo.CartSkuVO;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.shoptnt.framework.sncreator.SnCreator;
import cn.shoptnt.framework.util.CurrencyUtil;
import cn.shoptnt.framework.util.DateUtil;
import cn.shoptnt.model.base.SubCode;
import cn.shoptnt.model.trade.complain.enums.ComplainSkuStatusEnum;
import cn.shoptnt.model.trade.order.dto.OrderDTO;
import cn.shoptnt.model.trade.order.enums.OrderServiceStatusEnum;
import cn.shoptnt.model.trade.order.vo.OrderParam;
import cn.shoptnt.model.trade.order.vo.OrderSkuVO;
import cn.shoptnt.service.trade.order.OrderCenterManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 订单中心业务实现
 * @author: liuyulei
 * @create: 2020-03-23 18:39
 * @version:1.0
 * @since:7.1.5
 **/
@Service
public class OrderCenterManagerImpl implements OrderCenterManager {


    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    SnCreator snCreator;

    /**
     * 创建订单对象
     * @param orderParam  订单参数
     * @return 订单DTO
     */
    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public OrderDTO createOrder(OrderParam orderParam) {
        //处理订单数据
        OrderDTO order = new OrderDTO(orderParam);
        //填充订单数据
        fillOrder(order, orderParam);

        return order;
    }

    /**
     * 填充订单数据
     *
     * @param order      订单DTO
     * @param orderParam 订单参数
     */
    private void fillOrder(OrderDTO order, OrderParam orderParam) {
        //生成订单编号
        String orderSn = "" + snCreator.create(SubCode.ORDER);
        //订单创建时间
        long createTime = DateUtil.getDateline();
        //创建时间
        order.setCreateTime(createTime);
        //获取订单价格
        double orderTotalPrice = order.getPrice().getTotalPrice();
        //获取订单运费
        double freightPrice = order.getPrice().getFreightPrice();

        List<OrderSkuVO> skus = new ArrayList<>();
        //获取订单中sku信息
        //获取参与满减活动商品总数-1的数值（为了兼容金额比例无法整除而导致多个商品的退款金额总和与退款金额不一致的问题）
        List<OrderSkuVO> skuVOList=orderParam.getSkuParam().stream().sorted(Comparator.comparing(OrderSkuVO::getSubtotal)).collect(Collectors.toList());
        int num =  skuVOList.size() - 1;
        //订单中sku实际支付的金额
        Double surplusFmPrice = 0.00D;
        //店铺优惠券金额
        Double shopCoupon = order.getPrice().getCouponPrice();
        for (int i = 0; i < skuVOList.size(); i++) {
            OrderSkuVO orderSkuVO = skuVOList.get(i);
            if( shopCoupon>0){
                if (i != num) {
                    //使用优惠券前的金额
                    Double coupon =  CurrencyUtil.add(CurrencyUtil.sub(orderTotalPrice,freightPrice),shopCoupon);
                    //优惠的金额
                    double discount = CurrencyUtil.div(CurrencyUtil.mul(shopCoupon, orderSkuVO.getActualPayTotal()), coupon);
                    //实际总额
                    double total = CurrencyUtil.sub(orderSkuVO.getActualPayTotal(), discount);
                    //实际总额
                    orderSkuVO.setActualPayTotal(total);
                    //商品实际支付单价
                    orderSkuVO.setPurchasePrice( CurrencyUtil.div(total, orderSkuVO.getNum()));
                    orderSkuVO.setSubtotal(total);

                    //计算剩余的满减总额
                    surplusFmPrice = CurrencyUtil.add(surplusFmPrice, discount);
                } else {
                    //剩余优惠金额
                    Double surplus = CurrencyUtil.sub(order.getPrice().getCouponPrice(), surplusFmPrice);
                    //当前商品付款金额=订单金额总计-已支付的总额
                    Double actualPay = CurrencyUtil.sub(orderSkuVO.getActualPayTotal(), surplus);
                    orderSkuVO.setPurchasePrice( CurrencyUtil.div(actualPay,orderSkuVO.getNum()));
                    orderSkuVO.setActualPayTotal(actualPay);
                    orderSkuVO.setSubtotal(actualPay);
                }
            }
            orderSkuVO.setServiceStatus(OrderServiceStatusEnum.NOT_APPLY.name());
            orderSkuVO.setComplainStatus(ComplainSkuStatusEnum.NO_APPLY.name());
            skus.add(orderSkuVO);

        }

        order.setOrderSkuList(skus);
        order.setSn(orderSn);

        logger.debug("订单[" + order.getSn() + "]的price:",order.getPrice());

        //重新计算优惠金额
        order.getPrice().reCountDiscountPrice();

        //如果使用的是站点优惠券
        if (orderParam.getIsSiteCoupon() != null && orderParam.getIsSiteCoupon()) {

            //分配平台优惠券优惠金额
            List<GoodsCouponPrice> couponGoodsList = orderParam.getCouponGoodsList();
            //参与优惠的sku列表
            ArrayList<OrderSkuVO> newList = new ArrayList<>();
            for (OrderSkuVO orderSkuVO : skus) {
                for (GoodsCouponPrice goodsCouponPrice : couponGoodsList) {
                    if (orderSkuVO.getSkuId().equals(goodsCouponPrice.getSkuId())) {
                        newList.add(orderSkuVO);
                    }
                }
            }
            //使用优惠券sku的价格总计
            double sum = newList.stream().mapToDouble(OrderSkuVO::getActualPayTotal).sum();
            if (newList.size() > 0) {
                for (int i = 0; i < newList.size(); i++) {
                    OrderSkuVO skuVO = newList.get(i);
                    if (newList.size() == 1) {
                        skuVO.setPurchasePrice(skuVO.getPurchasePrice() - CurrencyUtil.div(orderParam.getCouponTotalPrice(), skuVO.getNum()));
                        skuVO.setActualPayTotal(skuVO.getActualPayTotal() - orderParam.getCouponTotalPrice());
                    } else {
                        if (i != newList.size() - 1) {

                            //优惠的金额
                            double discount = CurrencyUtil.div(CurrencyUtil.mul(orderParam.getCouponTotalPrice(), skuVO.getActualPayTotal()), sum);
                            //实际总额
                            double total = CurrencyUtil.sub(skuVO.getActualPayTotal(), discount);
                            //实际总额
                            skuVO.setActualPayTotal(total);
                            //商品实际支付单价
                            skuVO.setPurchasePrice( CurrencyUtil.div(total, skuVO.getNum()));
                            skuVO.setSubtotal(total);

                            //计算剩余的满减总额
                            surplusFmPrice = CurrencyUtil.add(surplusFmPrice, discount);
                        } else {
                            //剩余优惠金额
                            Double surplus = CurrencyUtil.sub(orderParam.getCouponTotalPrice(), surplusFmPrice);
                            //当前商品付款金额=订单金额总计-已支付的总额
                            Double actualPay = CurrencyUtil.sub(skuVO.getActualPayTotal(), surplus);
                            skuVO.setPurchasePrice(CurrencyUtil.div(actualPay, skuVO.getNum()));
                            skuVO.setActualPayTotal(actualPay);
                            skuVO.setSubtotal(actualPay);
                        }
                    }
                }
            }
            //此订单总价减去该订单可分享的站点优惠金额
            orderTotalPrice = CurrencyUtil.sub(order.getPrice().getTotalPrice(), orderParam.getCouponTotalPrice() == null ? 0.00 : orderParam.getCouponTotalPrice());
        }
        if(orderTotalPrice < 0){
            orderTotalPrice = 0.0;
        }
        order.setNeedPayMoney(orderTotalPrice);
        order.setOrderPrice(orderTotalPrice);
    }

}
